// import com.alibaba.druid.DbType;
// import com.alibaba.druid.sql.SQLUtils;
// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor*;

// import java.util.ArrayList;
// import java.util.std::list;
#pragma once
#include <string>
#include <list>

#include "../SQLStatement.h"
#include "../SQLObjectImpl.h"
#include "../SQLReplaceable.h"
#include "SQLInsertInto.h"
#include "../../../utils/common_ptr.h"

class SQLExpr;
class SQLObject;
class Object;
class SQLASTVisitor;
class SQLWithSubqueryClause;
class DbType;

class SQLInsertStatement_ValuesClause : public SQLObjectImpl, public SQLReplaceable
{
public:
  static SQLExpr_list_ptr  emptyListSQLExpr;
  SQLExpr_list_ptr  values;
  string_ptr  originalString;
  int replaceCount;

  SQLInsertStatement_ValuesClause();
  SHAREDOBJECT(SQLInsertStatement_ValuesClause);

  // SQLInsertStatement_ValuesClause *clone();
  virtual SQLObject_ptr clone();

  BOOL_ptr replace(SQLExpr_ptr expr, SQLExpr_ptr target);

  SQLInsertStatement_ValuesClause(SQLExpr_list_ptr  values);

  SQLInsertStatement_ValuesClause(SQLExpr_list_ptr  values, SQLObject_ptr parent);

  void addValue(Object_ptr value);

  void addValue(SQLExpr_ptr value);

  SQLExpr_list_ptr  getValues();

  void accept0(SQLASTVisitor_ptr visitor);

  string_ptr  getOriginalString();

  void setOriginalString(string_ptr  originalString);

  int getReplaceCount();

  void incrementReplaceCount();
};

class SQLInsertStatement : virtual public SQLInsertInto, virtual public SQLStatement
{
public:
  SQLWithSubqueryClause_ptr with;
  BOOL_ptr upsert; // for phoenix

  SQLInsertStatement();
  SHAREDOBJECT(SQLInsertStatement);

  void cloneTo(SQLInsertStatement_ptr x);

  // SQLInsertStatement *clone();
  virtual SQLObject_ptr clone();

  void accept0(SQLASTVisitor_ptr visitor);

  SQLObject_list_ptr getChildren();

  BOOL_ptr isUpsert();

  void setUpsert(BOOL_ptr upsert);

  DbType_ptr  getDbType();

  void setDbType(DbType_ptr  dbType);

  BOOL_ptr isAfterSemi();

  void setAfterSemi(BOOL_ptr afterSemi);

  SQLWithSubqueryClause_ptr getWith();

  void setWith(SQLWithSubqueryClause_ptr with);

  string_ptr  toString();
};
